package com.tbit.main.controller;

import com.alibaba.fastjson.JSONObject;
import com.tbit.main.common.JsonResult;
import com.tbit.main.constant.*;
import com.tbit.main.exception.BaseException;
import com.tbit.main.h2.pojo.ParkPoint;
import com.tbit.main.pojo.*;
import com.tbit.main.service.*;
import com.tbit.main.util.Assert;
import com.tbit.main.util.DateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.UUID;

/**
 * 蓝牙操作日志
 *
 * @author LMY
 * @create 2020-11-19 16:06
 */
@RestController
@RequestMapping("/orderLog")
public class OrderLogController {

    @Autowired
    private OrderLogService orderLogService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private MachineService machineService;
    @Autowired
    private AccountUserService accountUserService;
    @Autowired
    private MachineStatusService machineStatusService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private AccountConfigService accountConfigService;
    @Autowired
    private DataService dataService;
    @Resource
    private MachineOccupyService machineOccupyService;
    @Resource
    private ParkPointService parkPointService;
    @Autowired
    private ParkService parkService;
    @Autowired
    private MachineBorrowService machineBorrowService;

    /**
     * 添加
     *
     * @param token
     * @param orderLog
     */
    @RequestMapping("/insert")
    public void insert(String token, OrderLog orderLog) {
        AccountUser accountUser = tokenService.getAccount(token);

        Assert.hasLength(orderLog.getUserCode(), "Machine.userCode.notNull");
        Assert.hasLength(orderLog.getChannelType().toString(), "OrderLog.channelType.notNull");
        Assert.hasLength(orderLog.getOrderContent(), "OrderLog.rspContent.notNull");
        Assert.hasLength(orderLog.getOrderSource().toString(), "OrderLog.orderSource.notNull");
        Assert.hasLength(orderLog.getOrderType(), "OrderLog.orderType.notNull");
        Assert.hasLength(orderLog.getBusinessType().toString(), "OrderLog.businessType.notNull");

        /**查询设备信息*/
        Machine machine = machineService.getByUseCode(orderLog.getUserCode());
        if (machine == null) {
            throw new BaseException("Machine.notExist");
        }

        /**设备权限判断*/
        machineService.auth(accountUser.getAgents(), machine.getMachineId());

        orderLog.setOpType(accountUser.getAccountUserType());
        orderLog.setOpId(accountUser.getAccountUserId());
        orderLog.setAccountUserId(accountUser.getAccountUserId());
        orderLog.setOpTime(DateTimeUtil.getNowTime());
        String serNO = UUID.randomUUID().toString();
        orderLog.setOrderSerNo(serNO);
        orderLog.setMachineId(machine.getMachineId());
        orderLog.setMachineNo(machine.getMachineNO());
        if (orderLog.getRemark() == null) {
            orderLog.setRemark("运维记录蓝牙操作");
        }

        String nowTime = DateTimeUtil.getNowTime();
        orderLog.setRspRet(1);
        orderLog.setRspDt(nowTime);
        orderLog.setRspContent("1");

        if (orderLog.getOrderContent().equals(ControlTypeConstant.MACHINE_CONTROL_BAT_UNLOCK)) {
            MachineStatus machineStatus = machineStatusService.getByMachineId(machine.getMachineId());
            if (machineStatus != null) {
                PowerChangeLog pcl = new PowerChangeLog();
                pcl.setAccountId(machine.getAccountId());
                pcl.setMachineId(machine.getMachineId());
                pcl.setUserCode(machine.getUserCode());
                pcl.setMachineNO(machine.getMachineNO());
                pcl.setUserMainId(accountUser.getAccountUserId());
                pcl.setChangeTime(DateTimeUtil.getNowTime());
                pcl.setOldSoc(machineStatus.getSocPercent());
                pcl.setMachineType(machine.getMachineType());
                pcl.setRemark("蓝牙换电前电压=" + machineStatus.getBatteryEU() + ";");
                pcl.setAuditorId(1);
                pcl.setIsValid(0);
                /**添加到redis*/
                redisService.add(RedisConstant.REDIS_TER_BATTERY_CHANGE + machine.getMachineNO(), JSONObject.toJSONString(pcl), 1200);
                /**添加到redismap*/
                redisService.set(RedisConstant.REDIS_TER_BIKE_BATTERY_CHANGE_MAP, machine.getMachineNO(), String.valueOf(System.currentTimeMillis()));
            }
        } else if (orderLog.getOrderContent().equals(ControlTypeConstant.CONTROL_TYPE_UNLOCK)) { // 开锁

            // 添加运维占用
            addAccountUserOccupy(machine, accountUser);

            /* 取消车辆站点绑定*/
            machineService.parkMachineInside(machine.getMachineId(), null, 0);

            /**删除临停缓存*/
            parkService.del(machine.getMachineId());

        } else if (orderLog.getOrderContent().equals(ControlTypeConstant.CONTROL_TYPE_LOCK)) { // 关锁

            /* 删除数据库记录*/
            machineOccupyService.del(machine.getMachineId());

            /* 取消车辆站点绑定*/
            MachineStatus machineStatus = machineStatusService.getByMachineId(machine.getMachineId());
            if (machineStatus != null) {

                /* 判断是否是禁停区*/
                AccountConfig ac = dataService.getAccountConfig(machine.getAccountId());
                if (ac != null && ac.getReturnModel() == 0) {

                    /* 重新判断站点 */
                    Point point = new Point(machineStatus.getLon(), machineStatus.getLat());
                    ParkPoint parkPointNew = parkPointService.checkInParkPointNew(machine.getAccountId(), point, 100, null);

                    if (parkPointNew != null) {
                        machineService.put(new ParkMachine(parkPointNew.getParkPointId(), machine.getMachineId(), parkPointNew.getInside()));
                    } else {
                        machineService.parkMachineInside(machine.getMachineId(), null, 0);
                    }

                }
            }

            MachineBorrow machineBorrow = machineBorrowService.getByMachineId(machine.getMachineId());
            // 借车，并且没有临停记录
            if (null != machineBorrow && parkService.getByMachineId(machine.getMachineId()) == null) {
                /**增加临停缓存*/
                Park park = new Park();
                park.setAccountId(machine.getAccountId());
                park.setUserId(machineBorrow.getUserId());
                park.setMachineId(machine.getMachineId());
                park.setStartTime(nowTime);
                park.setRemark("运维蓝牙关锁标记临停");
                parkService.insert(park);
            }
            redisService.del(RedisConstant.REDIS_TER_BATTERY_CHANGE + machine.getMachineNO());
            redisService.del(RedisConstant.REDIS_TER_BIKE_PUSH_MACHINE_USER_CODE + machine.getUserCode());

        } else if (orderLog.getOrderContent().equals(ControlTypeConstant.CONTROL_TYPE_UNSTART)) {
            // 添加运维占用
            addAccountUserOccupy(machine, accountUser);
            redisService.add(RedisConstant.REDIS_TER_BIKE_PUSH_MACHINE_USER_CODE + machine.getUserCode(), machine.getUserCode());
        }

        orderLogService.insert(orderLog);
    }

    /**
     * 添加运维占用
     *
     * @param machine     车辆
     * @param accountUser 运维人员
     */
    private void addAccountUserOccupy(Machine machine, AccountUser accountUser) {
        MachineOccupy machineOccupy = machineOccupyService.getByMachineId(machine.getMachineId());
        if (machineOccupy != null && !machineOccupy.getAccountUserId().equals(accountUser.getAccountUserId())) {
            throw new BaseException("WorkOrder.occupy.notOperate");
        }

        AccountConfig accountConfig = dataService.getAccountConfig(machine.getAccountId());

        Integer value = dataService.getRoleConfig(accountUser.getAccountUserType() + RoleConfigConstant.MAIN_LOCK_VEHICLE);
        if (value != null && value.equals(1) && accountConfig != null) {
            /* 运维占用最大数判断 */
            if (accountConfig.getOccupyMax() != null && !accountConfig.getOccupyMax().equals(0)) {
                Integer occupy = machineOccupyService.getByAccountUserId(accountUser.getAccountUserId());
                if (occupy >= accountConfig.getOccupyMax()) {
                    throw new BaseException("Machine.occupyMax.exist");
                }
            }
        }

        MachineOccupy mo = new MachineOccupy(machine.getAccountId(), accountUser.getAccountUserId(), machine.getMachineId(), DateTimeUtil.getNowTime());

        // 添加占用
        MachineOccupy machineOccupyDb = machineOccupyService.getByMachineId(mo.getMachineId());
        if (machineOccupyDb == null) {
            machineOccupyService.insert(mo);
        }
    }

    /**
     * 判断蓝牙换电是否允许
     *
     * @param token
     * @param userCode
     */
    @RequestMapping("/getMachinePower")
    public JsonResult getMachinePower(String token, String userCode) {

        AccountUser accountUserToken = tokenService.getAccount(token);

        /**查询设备信息*/
        Machine machine = machineService.getByUseCode(userCode);
        if (machine == null) {
            throw new BaseException("Machine.notExist");
        }

        /**设备权限判断*/
        machineService.auth(accountUserToken.getAgents(), machine.getMachineId());

        MachineStatus machineStatus = machineStatusService.getByMachineId(machine.getMachineId());

        /**换电阈值配置*/
        AccountConfig accountConfig = accountConfigService.getByAccountId(machine.getAccountId());
        Integer values = dataService.getRoleConfig(accountUserToken.getAccountUserType() + RoleConfigConstant.MAIN_CHANGE_BATTERY);

        /**普通运维人员不能还低于指定阈值的车辆*/
        if (accountConfig != null && machineStatus.getSocPercent() > accountConfig.getSocLimit()) {
            if (values != null && values.equals(1)) {
                throw new BaseException("Machine.soc.over");
            }
        }
        return JsonResult.succ();
    }

    /**
     * 查询统计
     */
    @RequestMapping("/query")
    public JsonResult getByTime(String token, Integer accountId, Integer userMainId, String userCode, String startTime, String endTime, Integer rowCount, Integer pageNO) {
        AccountUser accountUserToken = tokenService.getAccount(token);
        Assert.notNull(accountId, "AccountUser.agentId.notNull");
        Assert.hasLength(startTime, "System.startTime.notNull");
        Assert.hasLength(endTime, "System.endTime.notNull");

        /*默认值*/
        if (rowCount == null || rowCount < 1) {
            rowCount = 10;
        }
        if (pageNO == null || pageNO < 1) {
            pageNO = 1;
        }

        Integer userType = null;
        if (userCode != null) {
            /**查询设备信息*/
            Machine machine = machineService.getByUseCode(userCode);
            if (machine == null) {
                throw new BaseException("Machine.notExist");
            }

            /**设备权限判断*/
            machineService.auth(accountUserToken.getAgents(), machine.getMachineId());
        } else {
            AccountUser accountUser = accountUserService.getAccountUserById(userMainId);

            /**账号类型转换*/
            if (accountUser.getSubRoleType() == 0) {//品牌、加盟商、区域代理商
                userType = accountUser.getAccountType();
            } else if (accountUser.getSubRoleType() == 1) {//运维管理员
                userType = UserConstant.ACCOUNT_MAINTAIN_MANAGER;
            } else if (accountUser.getSubRoleType() == 2) {//运维人员
                userType = UserConstant.ACCOUNT_MAINTAIN;
            } else {
                userType = accountUser.getSubRoleType();
            }

        }

        /*获取总数*/
        Integer count = orderLogService.queryCount(accountId, userMainId, userCode, startTime, endTime, userType);

        List<OrderLog> orderLogs = orderLogService.queryPage(accountId, userMainId, userCode, startTime, endTime, rowCount, pageNO, userType);

        for (OrderLog orderLog : orderLogs) {
            MainControlLog mainControlLog = new MainControlLog();
            mainControlLog.setMachineNO(orderLog.getMachineNo());
            mainControlLog.setOperaTime(orderLog.getOpTime());
            if (orderLog.getOrderContent() == null) {
                orderLog.setOrderContent(orderLog.getOpType() + "");
            }
            switch (orderLog.getOrderType()) {
                case "1":
                    mainControlLog.setRemark(ControlType.MACHINE_CONTROL_UNLOCK_N);
                    break;
                case "11":
                    mainControlLog.setRemark(ControlType.MACHINE_CONTROL_LOCK_N);
                    break;
                case "15":
                    mainControlLog.setRemark(ControlType.MACHINE_CONTROL_BAT_UNLOCK_N);
                    break;
                case "16":
                    mainControlLog.setRemark(ControlType.MACHINE_CONTROL_BAT_LOCK_N);
                    break;
                case "8":
                    mainControlLog.setRemark(ControlType.MACHINE_CONTROL_FIND_N);
                    break;
                case "9":
                    mainControlLog.setRemark(ControlType.MACHINE_CONTROL_DW_N);
                    break;
                case "22":
                    mainControlLog.setRemark(ControlType.MACHINE_CONTROL_OPEN_TK_N);
                    break;
                case "23":
                    mainControlLog.setRemark(ControlType.MACHINE_CONTROL_CLOSE_TK_N);
                    break;
                case "48":
                    mainControlLog.setRemark(ControlType.MACHINE_CONTROL_CLOSE_ZTTZ_N);
                    break;
                case "12":
                    mainControlLog.setRemark(ControlType.MACHINE_CONTROL_COERCE_LOCK_N);
                    break;
            }
            mainControlLog.setUserCode(orderLog.getUserCode());
            mainControlLog.setUserMainId(orderLog.getAccountUserId());
            if (orderLog.getRemark().contains(":")) {
                int index = orderLog.getRemark().lastIndexOf(":");
                mainControlLog.setUserMainName(orderLog.getRemark().substring(index + 1));
            }
            mainControlLog.setAccountId(accountId);
        }

        JsonResult result = JsonResult.succ(orderLogs);
        result.setTotal(count);
        return result;
    }

}
